#include "line_add_corner.h"
#include "../../layout/layout.hpp"
#include "../../undoRedo/undoRedo.hpp"
#include "../../utils//render_point.h"
#include "../../utils/kutils.h"
#include "../../utils/render_line.h"
#include "../../utils/shader.h"

namespace qbe::LineAddCorner {
void exit(ecs::Query query, state::AllModeType enter_mode) {
  return;
  auto& param = query.get_resource<LineAddCornerModel>();
  auto& state = query.get_resource<state::State>();
  if (std::get<state::EditingModeType>(enter_mode) == state::EditingModeType::LineAddCorner) {
    param.is_exit = false;
  } else {
    param.is_exit = true;
    param.m_clicked_num = 0;
    param.m_is_point_on_line = false;
    param.m_point_in_splitlines_position = 0;
    if (param.selected_line)
      (*param.selected_line) = param.old_path;

    auto& ecs_reg = query.get_reg();
    for (auto [e, switch_node] : ecs_reg.view<LineAddCornerTag, vsg::ref_ptr<vsg::Switch>>().each()) {
      switch_node->setAllChildren(false);
      switch_node->children.clear();
    }
    param.render_point = nullptr;
    param.render_line = nullptr;
  }
}
void init(entt::registry& reg, ecs::Commands commands, ecs::Query query) {
  auto& state = query.get_resource<state::State>();
  state.addExitCall(state::EditingModeType::LineAddCorner, exit);

  auto options = query.get_resource<vsg::ref_ptr<vsg::Options>>();
  for (auto [e, tran] : reg.view<render::SceneTag, vsg::ref_ptr<vsg::MatrixTransform>>().each()) {
    // 创建 Switch
    auto switchObject = vsg::Switch::create();
    tran->addChild(switchObject);
    commands.spawn(LineAddCornerTag{}, switchObject);
  }
}
void update(entt::registry& ecs_reg, ecs::Query query, ecs::Bus& bus, ecs::EventWriter<msg::RenderEvent> event) {
  return;
  auto& state = query.get_resource<state::State>();

  // 仅在模式执行
  if (state.getEditingMode() != state::EditingModeType::LineAddCorner)
    return;

  //获取当前操作的Cell
  auto& cmd = query.get_resource<layout::CellCmd>();
  auto cell = cmd.get_cell();
  auto& reg = cell->reg;
  auto& cell_state = query.get_resource<layout::CellState>();

  auto& axis_t = query.get_resource<axis::Axis>();

  auto& param = query.get_resource<LineAddCornerModel>();
  auto& layout_cmd = query.get_resource<layout::LayoutCmd>();

  //获取undo/red0
  auto& unredoMoudel = query.get_resource<undoRedoT::UndoRedoModule>();

  if (param.render_point == nullptr) {
    for (auto [e, switch_node] : ecs_reg.view<LineAddCornerTag, vsg::ref_ptr<vsg::Switch>>().each()) {
      switch_node->setAllChildren(true);
      auto options = query.get_resource<vsg::ref_ptr<vsg::Options>>();
      std::shared_ptr<utils::TempRender::RenderLine> render_line =
          std::make_shared<utils::TempRender::RenderLine>(options, std::vector<qlib::Path::s_ptr>{});
      switch_node->addChild(true, render_line->switchObject);
      render_line->setLayerType(vsg::vec4(1.0, 0.0, 1.0, 1.0), "B1");
      param.render_line = render_line;

      std::shared_ptr<utils::TempRender::RenderPoint> render_point =
          std::make_shared<utils::TempRender::RenderPoint>(options, std::vector<qlib::Label::s_ptr>{});
      switch_node->addChild(true, render_point->switchObject);
      //render_line->setLayerType(vsg::vec4(1.0, 0.0, 1.0, 1.0), "B1");
      param.render_point = render_point;
    }
    bus.send<qbe::UiMessage::OperatorInfoMessage>(
        qbe::UiMessage::OperatorInfoMessage{QString(QObject::tr("mode: Line Add Corner | Select the skeleton line to be operated on"))});
  }

  {
    auto res = bus.receive<UiMessage::CancelDrawing>();
    if (!res.empty()) {
      //ESC退出逻辑
      if (param.m_clicked_num != 0) {
        param.is_exit = true;
        param.m_clicked_num = 0;
        param.m_is_point_on_line = false;
        param.m_point_in_splitlines_position = 0;
        if (param.selected_line)
          (*param.selected_line) = param.old_path;
        param.render_point->setShowHide(false);
        param.render_line->setShowHide(false);
        bus.send<qbe::UiMessage::OperatorInfoMessage>(
            qbe::UiMessage::OperatorInfoMessage{QString(QObject::tr("mode: Line Add Corner | Select the skeleton line to be operated on"))});
      } else {
        state.switchMode(state::EditingModeType::None);
        for (auto [e, switch_node] : ecs_reg.view<LineAddCornerTag, vsg::ref_ptr<vsg::Switch>>().each()) {
          switch_node->setAllChildren(false);
          switch_node->children.clear();
        }
        param.render_point = nullptr;
        param.render_line = nullptr;
        return;
      }
    }
  }

  {
    auto res = bus.receive<UiMessage::CompleteDrawing>();
    if (!res.empty()) {
      //enter确定快捷建
    }
  }

  if (param.m_clicked_num == 0) {
    param.selected_line.reset();

    state.switchMode(state::SelectModeType::Overall);
    //获取选择对象
    std::vector<entt::entity> pre_select;
    for (auto [e] : reg.view<select::HoverTag>().each()) {
      auto _ptr = reg.try_get<qlib::Path::s_ptr>(e);
      if (_ptr) {
        pre_select.push_back(e);
      }
    }

    if (pre_select.empty())
      return;

    //获取实体的组件，不存在返回为nullptr
    auto ptr = reg.try_get<std::shared_ptr<qlib::Path>>(pre_select[0]);
    if (ptr == nullptr)
      return;
    if ((*ptr)->type != qlib::PathType::Spine)
      return;

    param.selected_line = *ptr;
    param.sel_line_entity = pre_select[0];
  }

  std::shared_ptr<qlib::Path> selected_line = param.selected_line;

  auto& hand = query.get_resource<vsg::ref_ptr<input::HandleBundle>>();

  //鼠标移动
  if (hand->mouse_move) {
    if (param.m_clicked_num == 0) {
      param.m_is_point_on_line = false;
      qlib::Vec2dArray point_array;
      selected_line->path_spines(point_array);

      //判断在那段线上生成折角
      for (int i = 0; i < point_array.size() - 1; ++i) {
        qlib::Vec2d flex_path_begin = point_array[i];
        qlib::Vec2d flex_path_end = point_array[i + 1];
        // 点是否在线上
        bool is_on_line = auxiliary::pointIsSegmentInternal(qlib::Vec2d(axis_t.real_x, axis_t.real_y), flex_path_begin, flex_path_end, axis_t.scale);
        if (is_on_line == true) {
          param.m_is_point_on_line = true;
          param.m_point_in_splitlines_position = i;
          param.point_array = selected_line->spine.points;
          param.old_path = (*selected_line);

          param.render_point->setShowHide(true);
          auto point = std::make_shared<qlib::Label>();
          point->origin = qlib::Vec2d(axis_t.real_x, axis_t.real_y);
          param.render_point->updateData({point});
        }
      }
      if (param.m_is_point_on_line == false) {
        param.render_point->setShowHide(false);
      }
    } else if (param.m_clicked_num == 1) {
      const std::vector<qlib::Vec2d> point_array = param.point_array;
      qlib::Vec2d A = point_array[param.m_point_in_splitlines_position];
      qlib::Vec2d B = point_array[param.m_point_in_splitlines_position + 1];

      qlib::Vec2d Q1;
      qlib::Vec2d Q2;
      if (false == auxiliary::findPointsOnLine(A, B, qlib::Vec2d(axis_t.real_x, axis_t.real_y), Q1, Q2, axis_t.scale)) {
        return;
      }

      std::vector<qlib::Vec2d> insert_points;
      insert_points.push_back(Q1);
      insert_points.push_back(qlib::Vec2d(axis_t.real_x, axis_t.real_y));
      insert_points.push_back(Q2);

      // 更新点的坐标
      std::vector<qlib::Vec2d> new_point_array = point_array;
      new_point_array.insert(new_point_array.begin() + param.m_point_in_splitlines_position + 1, insert_points.begin(), insert_points.end());
      selected_line->spine.points = new_point_array;
      param.render_line->setShowHide(true);
      param.render_line->updateData({selected_line});

      param.render_point->setShowHide(true);
      auto point = std::make_shared<qlib::Label>();
      point->origin = qlib::Vec2d(axis_t.real_x, axis_t.real_y);
      param.render_point->updateData({point});
    }
  }

  //点击鼠标左键
  if (hand->mousePressed(vsg::ButtonMask::BUTTON_MASK_1)) {
    if (true == param.m_is_point_on_line && param.m_clicked_num == 0) {
      param.m_clicked_num = 1;
      unredoMoudel.start(cell);
      unredoMoudel.change(param.sel_line_entity);
      bus.send<qbe::UiMessage::OperatorInfoMessage>(
          qbe::UiMessage::OperatorInfoMessage{QString(QObject::tr("mode: Line Add Corner | Confirm the final location"))});
      return;
    }

    if (param.m_clicked_num == 1) {
      param.m_clicked_num = 0;
      //auto new_path = (*selected_line);
      //(*selected_line) = param.old_path;
      param.render_point->setShowHide(false);
      param.render_line->setShowHide(false);
      layout_cmd.update<qlib::Path::s_ptr>(param.sel_line_entity);
      //event.send(msg::RenderEvent{msg::RenderCode::CellUpdate});  //确定后版图更新
      layout_cmd.render_update();  //确定后版图更新
      unredoMoudel.end();
      bus.send<qbe::UiMessage::OperatorInfoMessage>(
          qbe::UiMessage::OperatorInfoMessage{QString(QObject::tr("mode: Line Add Corner | Select the skeleton line to be operated on"))});

      auto& event_writer = query.get_event_writer<select::Event>();
      // 清除预选标记
      for (auto [e] : reg.view<select::HoverTag>().each()) {
        reg.remove<select::HoverTag>(e);
      }
      for (auto [e] : reg.view<select::SelectTag>().each()) {
        reg.remove<select::SelectTag>(e);
      }
      event_writer.send({{select::Code::SelectCancel}});
      event_writer.send({{select::Code::HoverCancel}});
    }
  }
}
void post(entt::registry& reg, ecs::Commands commands, ecs::Query query, ecs::Bus& bus) {}

}  // namespace qbe::LineAddCorner